using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using ManagedUIFlow.Properties;

namespace ManagedUIFlow.Infrastructure.Services
{
    public class FlowViewServiceBuilder
    {
        private Func<IFlowViewService> _factoryThunk;
        private static readonly FlowViewServiceBuilder Instance = new FlowViewServiceBuilder();

        public FlowViewServiceBuilder()
        {
            SetFlowViewService(new ContinuationSessionFlowViewService());
        }

        public static FlowViewServiceBuilder Current {
            get {
                return Instance;
            }
        }        

        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
            Justification = "Calling method multiple times might return different objects.")]
        public IFlowViewService GetFlowViewService()
        {
            var controllerFactoryInstance = _factoryThunk();
            return controllerFactoryInstance;
        }

        public void SetFlowViewService(IFlowViewService flowViewService)
        {
            if (flowViewService == null) {
                throw new ArgumentNullException("flowViewService");
            }

            _factoryThunk = () => flowViewService;
        }

        public void SetFlowViewService(Type controllerFactoryType) {
            if (controllerFactoryType == null) {
                throw new ArgumentNullException("controllerFactoryType");
            }
            if (!typeof(IFlowViewService).IsAssignableFrom(controllerFactoryType))
            {
                throw new ArgumentException(
                    String.Format(
                        CultureInfo.CurrentUICulture,
                        Resources.ControllerBuilder_MissingIControllerFactory,
                        controllerFactoryType),
                    "controllerFactoryType");
            }

            _factoryThunk = delegate() {
                                           try {
                                               return (IFlowViewService)Activator.CreateInstance(controllerFactoryType);
                                           }
                                           catch (Exception ex) {
                                               throw new InvalidOperationException(
                                                   String.Format(
                                                       CultureInfo.CurrentUICulture,
                                                       Resources.ControllerBuilder_ErrorCreatingControllerFactory,
                                                       controllerFactoryType),
                                                   ex);
                                           }
            };
        }
    }
}